const path = require('path');
const webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const DllPlugin = require('webpack/lib/DllPlugin');
const HappyPack = require('happypack');
// 引入 ParallelUglifyPlugin 插件
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');

module.exports = {
    entry: {
        app: './src/main.js'
    },
    output: {
        path: path.resolve(__dirname, '../dist/src'),
        filename: "[name].[contenthash:8].bundle.js",
        publicPath: '/', // 确保资源在服务器能在根域名下正确访问
    },
    externals: {
        "vue": "Vue",
        "axios":"axios",
        "jquery":"$",
        "element-ui": "element-ui"
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    {
                        loader: 'happypack/loader?id=css-pack',
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            sourceMap: true,
                            config: {
                              path: './config/postcss.config.js'
                            }
                        }
                    }
                ]
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
			    loader: 'file-loader'
            },
            {
                test: /\.js$/,
                // loader: 'babel-loader',
                 //把对.js 的文件处理交给id为happyBabel 的HappyPack 的实例执行
                loader: 'happypack/loader?id=happyBabel',
                //排除node_modules 目录下的文件
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                loader: 'file-loader!url-loader',
                options: {
                    name: '[name].[ext]?[hash]'
                }
            }
        ]
    },
    resolve: {
        alias: {
            '@': path.resolve('src'),
            'vue': 'vue/dist/vue.esm.js',
        },
        extensions: ['.js', '.json', '.vue']
    },
    optimization: {
        runtimeChunk: {name: "manifest"},
        usedExports: true,
        splitChunks: {
            chunks: "async", // 共有三个值可选：initial(初始模块)、async(按需加载模块)和all(全部模块)
            minSize: 30000, // 模块超过30k自动被抽离成公共模块
            minChunks: 1, // 模块被引用>=1次，便分割
            maxAsyncRequests: 5,  // 异步加载chunk的并发请求数量<=5
            maxInitialRequests: 3, // 一个入口并发加载的chunk数量<=3
            name: true, // 默认由模块名+hash命名，名称相同时多个模块将合并为1个，可以设置为function
            automaticNameDelimiter: '~', // 命名分隔符
            cacheGroups: { // 缓存组，会继承和覆盖splitChunks的配置
                default: { // 模块缓存规则，设置为false，默认缓存组将禁用
                    minChunks: 2, // 模块被引用>=2次，拆分至vendors公共模块
                    priority: -20, // 优先级
                    reuseExistingChunk: true, // 默认使用已有的模块
                    minSize: 30000, // 被提取的模块必须大于30kb
                    maxAsyncRequests: 5, // 对于异步模块，生成的公共模块文件不能超出5个
                    maxInitialRequests: 3, // 对于入口模块，抽离出的公共模块文件不能超出3个
                },
                // vendor: {
                //     test: /node_modules/,
                //     chunks: "initial",
                //     name: "vendor",
                //     priority: 10,
                //     enforce: true
                // },
                // commons: {
                //     chunks: "initial",
                //     minSize: 0 ,
                //     name: "commons"
                // }
            }
        }
    },
    plugins: [
        new VueLoaderPlugin(),
        new webpack.BannerPlugin({
            banner: "this is filebase:[filebase]"
        }),
        new webpack.HashedModuleIdsPlugin(),
        new MiniCssExtractPlugin({
            filename: "main.[contenthash:8].css",
            chunkFilename: "main.[contenthash:8].css",
            ignoreOrder: false
        }),
        new HappyPack({
            //用id来标识 happypack处理那里类文件
            id: 'happyBabel',
            //如何处理  用法和loader 的配置一样
            loaders: [{
                loader: 'babel-loader?cacheDirectory=true',
            }]
        }),
        // 处理css文件
        new HappyPack({
            id: 'css-pack',
            loaders: ['css-loader']
        }),
        // 只要引入manifest.json就能知道哪些模块再dll文件中，在打包过程会忽略这些模块
        new webpack.DllReferencePlugin({
            context: path.resolve(__dirname, '..'), 
            manifest: require('../dist/plugins/vueplugin.manifest.json')
        }),
        new webpack.DllReferencePlugin({
            context: path.resolve(__dirname, '..'), 
            manifest: require('../dist/plugins/elementuiplugin.manifest.json')
        }),
    
    ]
};

